#include "Line.h"
#include <QDebug>

Line::Line()
{
    m_texture = 0;
}

Line::Line(QPoint* p1, QPoint* p2)
{
    m_texture = 0;
    m_vertexs.clear();
    m_vertexs.append(p1);
    m_vertexs.append(p2);
}

void Line::draw(QPainter* painter)
{
    QPoint p1 = *(vertexs().at(0));
    QPoint p2 = *(vertexs().at(1));

    double m = (double)(p2.y() - p1.y()) / (double)(p2.x() - p1.x());
    double b = p1.y() - p1.x() * m;


    if(p1.x() == p2.x())
    {
        int x = p1.x();
        for(int y = p1.y(); y <= p2.y(); y++)
        {
            QPoint p(x, y);
            paintPoint(p,painter);
        }
    }
    else
    {
        if(qAbs(m) < 1.0)
        {
            if(p2.x() < p1.x())
            {
                QPoint tempPoint;
                tempPoint = p1;
                p1 = p2;
                p2 = tempPoint;
            }
            paintPoint(p1,painter);
            int x = p1.x();
            float y = p1.y();
            for(x += 1; x <= p2.x(); x++)
            {
                y += m;
                QPoint p(x, y);
                paintPoint(p,painter);
            }
        }
        else
        {
            if(p2.y() < p1.y())
            {
                QPoint tempPoint;
                tempPoint = p1;
                p1 = p2;
                p2 = tempPoint;
            }

            for(int y = p1.y(); y <= p2.y(); y++)
            {
                int x = (y - b) / m;
                QPoint p(x, y);
                paintPoint(p,painter);
            }
        }
    }
}

QList<QPoint*> Line::pixelCoordenates()
{
    QList<QPoint*> points;
    QPoint p1 = *(vertexs().at(0));
    QPoint p2 = *(vertexs().at(1));

    double m = (double)(p2.y() - p1.y()) / (double)(p2.x() - p1.x());
    double b = p1.y() - p1.x() * m;

    if(p1.x() == p2.x())
    {
        int x = p1.x();
        for(int y = p1.y(); y <= p2.y(); y++)
        {
            QPoint* p = new QPoint(x, y);
            points.append(p);
        }
    }
    else
    {
        if(qAbs(m) < 1.0)
        {
            if(p2.x() < p1.x())
            {
                QPoint tempPoint;
                tempPoint = p1;
                p1 = p2;
                p2 = tempPoint;
            }

            for(int x = p1.x(); x <= p2.x(); x++)
            {
                int y = x * m + b;
                QPoint* p = new QPoint(x, y);
                points.append(p);
            }
        }
        else
        {
            if(p2.y() < p1.y())
            {
                QPoint tempPoint;
                tempPoint = p1;
                p1 = p2;
                p2 = tempPoint;
            }

            for(int y = p1.y(); y <= p2.y(); y++)
            {
                int x = (y - b) / m;
                QPoint* p = new QPoint(x, y);
                points.append(p);
            }
        }
    }
    return points;
}

QList<QPoint*> Line::projectedPoints(QList<QPoint*> originalPoints)
{
    QList<QPoint*> projectedPoints;

    QPoint p1r1 = *(originalPoints.at(0));
    QPoint p1r2 = *(vertexs().at(0));
    QPoint p2r2 = *(vertexs().at(1));

    QVector2D v1;
    QVector2D v2;

    QVector2D projectedVector;
    QPoint* projectedPoint;

    v2 = generateVector(p1r2,p2r2);
    foreach(QPoint* point,originalPoints)
    {
        v1 = generateVector(p1r1,*point);
        projectedVector = projectFromZeroUpToOne(v1,v2);
        projectedPoint = new QPoint(projectedVector.toPoint() + p1r2);
        projectedPoints.append(projectedPoint);
    }

    return projectedPoints;
}

QVector2D* Line::toVector2D()
{
    return new QVector2D(generateVector(*(m_vertexs.at(0)),*(m_vertexs.at(1))));
}

QColor Line::getInterpolatedColor(QPoint* p)
{
    float t = (p->x() - vertexs().at(0)->x())/(generateVector(*(vertexs().at(0)),*(vertexs().at(1))).x());
    t = (t < 0.0)?0.0:t;
    t = (t > 1.0)?1.0:t;
    int r = (int) ((1 - t) * colors().at(0)->red() + t * colors().at(1)->red());
    int g = (int) ((1 - t) * colors().at(0)->green() + t * colors().at(1)->green());
    int b = (int) ((1 - t) * colors().at(0)->blue() + t * colors().at(1)->blue());
    r = (r > 255)?255:r;
    r = (r < 0)?0:r;
    g = (g > 255)?255:g;
    g = (g < 0)?0:g;
    b = (b > 255)?255:b;
    b = (b < 0)?0:b;

    return QColor(r,g,b);
}

void Line::paintPoint(QPoint p,QPainter* painter)
{
    QPen pen(Qt::black, 2, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
    if (texture()) pen.setColor(*(texture()->color(p)));
    else pen.setColor(getInterpolatedColor(&p));
    painter->setPen(pen);
    painter->drawPoint(p);
}
